package service;


import org.apache.commons.collections.CollectionUtils;
import org.apache.flink.api.common.state.ListState;
import pojo.LogBean;
import pojo.RuleAutomicParam;
import pojo.RuleParam;
//import utils.RuleCalUtils;

import java.util.*;

public class UserActionSequenceQueryServiceImpl implements UserActionSequenceQueryService {


    public boolean UserActionSequenceQueryFromState(String deviceId,ListState<LogBean> eventstate, RuleParam ruleParam) throws Exception {
        //为了方便测试，我们用一个helper
        Iterable<LogBean> events = eventstate.get();
        //这里判断一些序列条件是否符合
        int i = UserActionSequenceQueryFromStateHelper(events, ruleParam);
        System.out.println("maxstep" + i);
        //如果满足，就修改最大的步数
        ruleParam.setMaxstep(i);
        //如果阈值大于最大的步数，就返回false
        return true;

    }

    /**
     * 第一种算法实现行为序列条件，可以实现需求，但有以下问题
     * 1，我们的状态里面events里面存放着用户的历史数据，，在内层循环为了记录下标如果我们先转成list,如果用户的数据量大，就会内存压力很大
     * 2，思路虽然也不难，但是算法的时间复杂度太高
     * TODO  需要改进
     *
     * @param events
     * @param ruleParam
     * @return
     */
    public int UserActionSequenceQueryFromStateHelper(Iterable<LogBean> events, RuleParam ruleParam) {
        //A    B A    B   C    H    D
        // A[P1=V3,P2=V5]   ====  B[P1=V3,P2=V5]  ====  D[P1=V3,P2=V5]
        //拿出用户的参数
        ArrayList<LogBean> logBeanslist = new ArrayList<>();
        CollectionUtils.addAll(logBeanslist, events.iterator());
        List<RuleAutomicParam> userActionsequenceParam = ruleParam.getUserActionsequenceParam();
        int maxstep = 0;
        int index = 0;
        for (RuleAutomicParam ruleAutomicParam : userActionsequenceParam) {
            boolean isfind = false;
            for (int i = index; i < logBeanslist.size(); i++) {
//                Boolean ismatch = RuleCalUtils.eventProfileMatchUseProfile(logBeanslist.get(i), ruleAutomicParam,true);
                //找到的时候就不用往下找了
                if (true) {
                    maxstep++;
                    isfind = true;
                    index = i + 1;
                    break;
                }
            }
            //TODO 优化一下，第一个找到了，外层循环如果第二个没找到，也要终止外层循环，不用往下找了，否则会出问题。
            if (!isfind) {
                break;
            }
        }
        return maxstep;
    }


    /**
     * 行为次序查询的方法优化
     *
     * @param events
     * @param ruleParam
     * @return
     */
    public int UserActionSequenceQueryFromStateHelper2(Iterable<LogBean> events, RuleParam ruleParam) {

        for (LogBean event : events) {
        }
        return 1;

    }


}



